package com.yjhh.chdataservice.service;

import com.yjhh.chdataservice.beans.PolicyInfoVo;
import com.yjhh.chdataservice.domain.PolicyInfo;
import com.yjhh.chdataservice.repository.PolicyInfoRepository;
import com.yjhh.chdataservice.util.BaseResultData;
import com.yjhh.chdataservice.util.CommonResultData;
import com.yjhh.chdataservice.util.DataConsts;
import com.yjhh.chdataservice.util.PageVO;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.criteria.*;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 公开查询ServiceImpl
 */
@Log4j2
@Service
public class PublicSearchServiceImpl implements PublicSearchService {

    @Autowired
    private PolicyInfoRepository policyInfoRepository;

    @Value("${attach.file.parentPath}")
    private String attachFileParentPath;

    @Override
    public BaseResultData savePolicyInfo(String ip, String title, String secondTitle, String icon, Integer policyType, Integer contentType, String content) {
        if (StringUtils.isBlank(title)) {
            return new BaseResultData(DataConsts.SavePolicyInfoResultCode.TILTE_IS_REQUIRED, DataConsts.SavePolicyInfoResultMsg.TILTE_IS_REQUIRED);
        }
        if (policyType == null) {
            return new BaseResultData(DataConsts.SavePolicyInfoResultCode.POLICY_TYPE_IS_REQUIRED, DataConsts.SavePolicyInfoResultMsg.POLICY_TYPE_IS_REQUIRED);
        }
        if (contentType == null) {
            return new BaseResultData(DataConsts.SavePolicyInfoResultCode.CONTENT_TYPE_IS_REQUIRED, DataConsts.SavePolicyInfoResultMsg.CONTENT_TYPE_IS_REQUIRED);
        }
        if (StringUtils.isBlank(content)) {
            return new BaseResultData(DataConsts.SavePolicyInfoResultCode.CONTENT_IS_REQUIRED, DataConsts.SavePolicyInfoResultMsg.CONTENT_IS_REQUIRED);
        }
        //检测政策title有没有重复的
        List<PolicyInfo> policyInfoList = policyInfoRepository.findByTitleAndDataFlag(StringUtils.trim(title), DataConsts.DataStatus.DATA_FLAG_OK);
        if (policyInfoList.size() > 0) {
            return new BaseResultData(DataConsts.SavePolicyInfoResultCode.TITLE_EXISTED, DataConsts.SavePolicyInfoResultMsg.TITLE_EXISTED);
        }
        PolicyInfo policyInfo = new PolicyInfo();
        policyInfo.setRequestIp(ip);
        policyInfo.setTitle(StringUtils.trim(title));
        policyInfo.setSecondTitle(StringUtils.trim(secondTitle));
        policyInfo.setIcon(icon);
        policyInfo.setPolicyType(policyType);
        policyInfo.setContentType(contentType);
        policyInfo.setContent(StringUtils.trim(content));

        policyInfoRepository.save(policyInfo);

        return new BaseResultData(HttpStatus.SC_OK, DataConsts.SavePolicyInfoResultMsg.SUC);
    }

    @Override
    public CommonResultData<PageVO<PolicyInfoVo>> findPolicyByPaging(Integer pageIndex, Integer pageSize, Integer policyType) {
        List<Sort.Order> orders = new ArrayList<>();
        orders.add(new Sort.Order(Sort.Direction.DESC, "createTime"));
        Pageable pageable = new PageRequest(pageIndex, pageSize, new Sort(orders));
        Page<PolicyInfo> page = policyInfoRepository.findAll(new Specification() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {
                Path<String> dataFlagPath = root.get("dataFlag");
                Path<String> policyTypePath = root.get("policyType");
                /**
                 * 连接查询条件, 不定参数，可以连接0..N个查询条件
                 */

                List<Predicate> list = new ArrayList();
                list.add(cb.equal(dataFlagPath, DataConsts.DataStatus.DATA_FLAG_OK));

                if (policyType != null && policyType.intValue() > 0) {
                    list.add(cb.equal(policyTypePath, policyType.intValue()));
                }
                query.where(list.toArray(new Predicate[0]));
                return null;
            }
        }, pageable);

        List<PolicyInfo> policyInfos = page.getContent();
        List<PolicyInfoVo> policyInfoVos = new ArrayList<>();
        for (PolicyInfo policyInfo : policyInfos) {
            PolicyInfoVo policyInfoVo = new PolicyInfoVo();
            try {
                BeanUtils.copyProperties(policyInfoVo, policyInfo);
            } catch (IllegalAccessException e) {
                log.error("BeanUtils.copyProperties:", e);
            } catch (InvocationTargetException e) {
                log.error("BeanUtils.copyProperties:", e);
            }
            policyInfoVos.add(policyInfoVo);
        }

        PageVO<PolicyInfoVo> pageVO = new PageVO<>();
        pageVO.setPageIndex(pageIndex);
        pageVO.setPageSize(pageSize);
        pageVO.setPageData(policyInfoVos);
        pageVO.setTotal(page.getTotalElements());
        return new CommonResultData(HttpStatus.SC_OK, "suc", pageVO);
    }

    @Override
    public CommonResultData<PolicyInfo> findPolicyInfo(String id) {
        PolicyInfo policyInfo = policyInfoRepository.findOne(id);
        return new CommonResultData(HttpStatus.SC_OK, "suc", policyInfo);
    }

    @Override
    public CommonResultData<String> uploadFile(String remortIP, MultipartFile file) throws IOException {
        log.info("uploadFile ip=" + remortIP);
        String originalFilename = file.getOriginalFilename();
        log.info("file name=" + originalFilename);
        String contentType = file.getContentType();
        log.info("file content type=" + contentType);
        if (file == null) {
            return new CommonResultData<>(HttpStatus.SC_BAD_REQUEST, "params error");
        }

        if (!StringUtils.endsWithIgnoreCase(originalFilename, "pdf") && !StringUtils.startsWithIgnoreCase(contentType, "image")) {
            return new CommonResultData<>(HttpStatus.SC_BAD_REQUEST, "目前只支持PDF和图片文件上传！");
        }

        String relativePath = File.separator + "policy" + File.separator + new Date().getTime() + "_" + originalFilename;
        File newFile = new File(attachFileParentPath + relativePath);
        if (!newFile.getParentFile().exists()) {
            newFile.getParentFile().mkdirs();
        }

        if (!file.isEmpty()) {
            BufferedOutputStream buffStream =
                    new BufferedOutputStream(new FileOutputStream(newFile));
            buffStream.write(file.getBytes());
            buffStream.close();
        } else {
            return new CommonResultData<>(org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR.value(), "Unable to upload. File is empty.");
        }

        return new CommonResultData(HttpStatus.SC_OK, "suc", relativePath);
    }

    @Override
    public CommonResultData delPolicy(String id) {
        PolicyInfo policyInfo = policyInfoRepository.findOne(id);
        if (policyInfo == null) {
            return new CommonResultData(HttpStatus.SC_BAD_REQUEST, "政策不存在！");
        }
        if (policyInfo.getDataFlag() != DataConsts.DataStatus.DATA_FLAG_OK) {
            return new CommonResultData(HttpStatus.SC_BAD_REQUEST, "政策已经被删除，不能重复删除！");
        }
        policyInfo.setDataFlag(DataConsts.DataStatus.DATA_FLAG_DELETED);
        policyInfoRepository.save(policyInfo);
        return new CommonResultData(HttpStatus.SC_OK, "删除成功！");
    }

    @Override
    public BaseResultData updatePolicy(String remoteIP, String id, String title, String secondTitle, String icon, Integer policyType, Integer contentType, String content) {
        if (StringUtils.isBlank(id)) {
            return new BaseResultData(DataConsts.UpdatePolicyInfoResultCode.POLICY_ID_IS_REQUIRED, DataConsts.UpdatePolicyInfoResultMsg.POLICY_ID_IS_REQUIRED);
        }
        if (StringUtils.isBlank(title)) {
            return new BaseResultData(DataConsts.UpdatePolicyInfoResultCode.TILTE_IS_REQUIRED, DataConsts.UpdatePolicyInfoResultMsg.TILTE_IS_REQUIRED);
        }
        if (policyType == null) {
            return new BaseResultData(DataConsts.UpdatePolicyInfoResultCode.POLICY_TYPE_IS_REQUIRED, DataConsts.UpdatePolicyInfoResultMsg.POLICY_TYPE_IS_REQUIRED);
        }
        if (contentType == null) {
            return new BaseResultData(DataConsts.UpdatePolicyInfoResultCode.CONTENT_TYPE_IS_REQUIRED, DataConsts.UpdatePolicyInfoResultMsg.CONTENT_TYPE_IS_REQUIRED);
        }
        if (StringUtils.isBlank(content)) {
            return new BaseResultData(DataConsts.UpdatePolicyInfoResultCode.CONTENT_IS_REQUIRED, DataConsts.UpdatePolicyInfoResultMsg.CONTENT_IS_REQUIRED);
        }

        PolicyInfo curPolicyInfo = policyInfoRepository.findOne(id);

        if (curPolicyInfo == null || curPolicyInfo.getDataFlag().intValue() != DataConsts.DataStatus.DATA_FLAG_OK.intValue()) {
            return new BaseResultData(DataConsts.UpdatePolicyInfoResultCode.DATA_IS_NOT_EXIST, DataConsts.UpdatePolicyInfoResultMsg.DATA_IS_NOT_EXIST);
        }

        //检测政策title有没有重复的
        List<PolicyInfo> policyInfoList = policyInfoRepository.findByTitleAndDataFlag(StringUtils.trim(title), DataConsts.DataStatus.DATA_FLAG_OK);
        if (policyInfoList.size() > 0) {
            PolicyInfo policyInfo = policyInfoList.get(0);
            if (!StringUtils.equals(policyInfo.getId(), curPolicyInfo.getId())) {
                return new BaseResultData(DataConsts.UpdatePolicyInfoResultCode.TITLE_EXISTED, DataConsts.UpdatePolicyInfoResultMsg.TITLE_EXISTED);
            }
        }

        curPolicyInfo.setRequestIp(remoteIP);
        curPolicyInfo.setTitle(StringUtils.trim(title));
        curPolicyInfo.setSecondTitle(StringUtils.trim(secondTitle));
        curPolicyInfo.setIcon(icon);
        curPolicyInfo.setPolicyType(policyType);
        curPolicyInfo.setContentType(contentType);
        curPolicyInfo.setContent(StringUtils.trim(content));

        policyInfoRepository.save(curPolicyInfo);

        return new BaseResultData(HttpStatus.SC_OK, DataConsts.SavePolicyInfoResultMsg.SUC);
    }
}
